package com.example.library_base.base.adapter

import android.util.SparseArray
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.core.util.containsKey
import androidx.core.util.size
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableList
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import com.example.library_base.base.BaseModel

abstract class BaseAdapter<T> constructor(@LayoutRes val layoutResId: Int) :
    RecyclerView.Adapter<BaseViewHolder>() {

    constructor() : this(0)

    private val observableListChangedCallback by lazy { ObservableListChangedCallback(this) }
    var mData: ObservableList<T> = ObservableArrayList()
    var mItemViewType: ItemViewType<T>? = null

    private val mHeaderView: SparseArray<BaseModel> = SparseArray()
    private val mFooterView: SparseArray<BaseModel> = SparseArray()

    //在Grid的布局中header view是否与Grid一致
    var headerViewAsFlowable = false

    //在Grid的布局中footer view是否与Grid一致
    var footerViewAsFlowable = false

    init {
        mData.addOnListChangedCallback(observableListChangedCallback)
    }

//    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
//        super.onAttachedToRecyclerView(recyclerView)
//        val manager = recyclerView.layoutManager
//        if (manager is GridLayoutManager) {
//            val defSpanSizeLookup = manager.spanSizeLookup
//            manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
//                override fun getSpanSize(position: Int): Int {
//                    val type = getItemViewType(position)
//                    if (type == ITEM_TYPE_HEADER && headerViewAsFlowable) {
//                        return 1
//                    }
//                    if (type == ITEM_TYPE_FOOTER && footerViewAsFlowable) {
//                        return 1
//                    }
////                    if (manager.spanSizeLookup == null){
////                        return
////                    }
//
//                    return 0
//                }
//            }
//        }
//    }

    override fun getItemViewType(position: Int): Int {
        return if (position < mHeaderView.size) {
            mHeaderView.keyAt(position)
        } else {
            var adjPosition = position - mHeaderView.size
            val adapterCount = mData.size
            if (adjPosition < adapterCount) {
                getDefItemViewType(adjPosition)
            } else {
                adjPosition -= adapterCount
                if (adjPosition < mFooterView.size) {
                    mFooterView.keyAt(adjPosition)
                } else {
                    -1
                }
            }
        }
    }

    protected open fun getDefItemViewType(position: Int): Int {
        return mItemViewType?.getDefItemViewType(mData, position) ?: super.getItemViewType(position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        when {
            mHeaderView.containsKey(viewType) -> {
                val binding = DataBindingUtil.inflate<ViewDataBinding>(
                    LayoutInflater.from(parent.context),
                    viewType,
                    parent,
                    false
                )
                return BaseViewHolder(binding)
            }
            mFooterView.containsKey(viewType) -> {
                val binding = DataBindingUtil.inflate<ViewDataBinding>(
                    LayoutInflater.from(parent.context),
                    viewType,
                    parent,
                    false
                )
                return BaseViewHolder(binding)
            }
            else -> {
                val binding = DataBindingUtil.inflate<ViewDataBinding>(
                    LayoutInflater.from(parent.context),
                    mItemViewType?.getLayoutId(viewType) ?: layoutResId,
                    parent,
                    false
                )
                return BaseViewHolder(binding)
            }
        }
    }

    override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
        val binding = DataBindingUtil.getBinding<ViewDataBinding>(holder.itemView)
        val viewType = holder.itemViewType

        when {
            mHeaderView.containsKey(viewType) -> {
                onHeaderBindItem(binding, mHeaderView.get(viewType))
            }
            mFooterView.containsKey(viewType) -> {
                onFooterBindItem(binding, mFooterView.get(viewType))
            }
            else -> {
                onBindItem(binding, mData[position - mHeaderView.size])
            }
        }
    }

    abstract fun onBindItem(binding: ViewDataBinding?, bean: T)

    abstract fun <H : BaseModel> onHeaderBindItem(binding: ViewDataBinding?, bean: H)

    abstract fun <H : BaseModel> onFooterBindItem(binding: ViewDataBinding?, bean: H)

    override fun getItemCount(): Int {
        return mData.size + mHeaderView.size + mFooterView.size
    }

    fun <H : BaseModel> addHeaderView(@LayoutRes header: Int, headerDate: H) {
        mHeaderView.put(header, headerDate)
        notifyItemInserted(mHeaderView.size - 1)
    }

    fun <H : BaseModel> addFooterView(@LayoutRes footer: Int, footerDate: H) {
        mFooterView.put(footer, footerDate)
        notifyItemInserted(mHeaderView.size + mData.size + (mFooterView.size - 1))
    }

}